package com.gitee.wsl.mathematics.vector.ext

import com.gitee.wsl.mathematics.vector.vec2.Vector2
import com.gitee.wsl.mathematics.vector.vec3.Vector3
import com.gitee.wsl.mathematics.vector.vec4.Vector4
import com.gitee.wsl.mathematics.vector.ext.times

fun<T:Number,V:Vector3<T, V>> Vector3<T, V>.refract(normal: Vector3<T, V>, reflectionRatio: T): V {
    //val cos = min((-this dot normal),zero + 1)
    val cos = min(-(this.dot(normal)), zero+1.0f)
    val rayPerp = reflectionRatio * (this +  normal * cos)
    val rayPara = normal * -sqrt(abs(1 - rayPerp.squaredLength))
    return rayPerp + rayPara
}

fun<T:Number,V: Vector2<T, V>> Vector2<T, V>.refract(normal: Vector2<T, V>, reflectionRatio: T): V {
    val cos = min(-(this.dot(normal)), zero+1.0f)
    val rayPerp = reflectionRatio * (this +  normal * cos)
    val rayPara = normal * -sqrt(abs(1 - rayPerp.squaredLength))
    return rayPerp + rayPara
}

fun<T:Number,V: Vector4<T, V>> Vector4<T, V>.refract(normal: Vector4<T, V>, reflectionRatio: T): V {
    val cos = min(-(this.dot(normal)), zero+1.0f)
    val rayPerp = reflectionRatio * (this +  normal * cos)
    val rayPara = normal * -sqrt(abs(1 - rayPerp.squaredLength))
    return rayPerp + rayPara
}

fun<T:Number,V: Vector2<T, V>> Vector2<T, V>.refract(normal: Vector2<T, V>): V {
    return this -  (2.0f * (normal dot this)) * normal
}

fun<T:Number,V: Vector3<T, V>> Vector3<T, V>.refract(normal: Vector3<T, V>): V {
    return this -  (2.0f * (normal dot this)) * normal
}


/*
inline fun reflect(i: Float2, n: Float2) = i - 2.0f * dot(n, i) * n
fun refract(i: Float2, n: Float2, eta: Float): Float2 {
    val d = dot(n, i)
    val k = 1.0f - eta * eta * (1.0f - sqr(d))
    return if (k < 0.0f) Float2(0.0f) else eta * i - (eta * d + sqrt(k)) * n
}*/
